package com.mbc.hr.manager;

import java.sql.SQLException;
import java.util.List;

import com.mbc.common.exception.ForeignConflictException;
import com.mbc.common.manager.AbstractMgr;
import com.mbc.common.param.CriteriaParams;
import com.mbc.common.utils.KeyGenerator;
import com.mbc.hr.data.DepartmentDataList;
import com.mbc.hr.entities.Department;

public class DepartmentMgr extends AbstractMgr {
	
	public DepartmentMgr(){}
	
	public DepartmentMgr(String sessionId){
		this.sessionId = sessionId;
	}
	
	public void create(Department department)throws Exception{
		openConnection();
		try {
			beginTransaction();
			department.setDepartmentID(KeyGenerator.generateKey(entityManager));
			entityManager.persist(department);
			commitTransaction();
		} catch (Exception e) {
			rollbackTransaction();
			throw e;
		} finally {
			closeConnection();
		}
	}
	
	public void update(Department department)throws Exception{
		openConnection();
		try {
			beginTransaction();
			entityManager.merge(department);
			commitTransaction();
		} catch (Exception e) {
			rollbackTransaction();
			throw e;
		} finally {
			closeConnection();
		}
	}
	
	public void delete(long departmentId)throws Exception{
		openConnection();
		try {
			beginTransaction();
			deleteRecursive(departmentId);
			commitTransaction();
		} catch (Exception e) {
			rollbackTransaction();
			if(e.getCause().getCause().getCause() instanceof SQLException){
				if(ForeignConflictException.FOREIGN_CONFLICT_ERROR_CODE == ((SQLException)e.getCause().getCause().getCause()).getErrorCode())
					throw new ForeignConflictException(e);
				else
					throw e;
			}
			else
				throw e;
		} finally {
			closeConnection();
		}
	}
	
	private void deleteRecursive(long id)throws Exception{
		try {
			List<Department> l_departmentList = entityManager.createNamedQuery("Department.findAllByParent", Department.class)
					.setParameter("parentID", id)
					.getResultList();
			for (Department l_department : l_departmentList) {
				deleteRecursive(l_department.getDepartmentID());
			}
			Department l_department = entityManager.find(Department.class, id);
			entityManager.remove(l_department);
		} catch (Exception e) {
			throw e;
		}
	}
	
	public Department find(long departmentId)throws Exception{
		openConnection();
		try {
			return entityManager.find(Department.class, departmentId);
		} catch (Exception e) {
			throw e;
		} finally {
			closeConnection();
		}
	}
	
	public DepartmentDataList getDepartments(CriteriaParams cri)throws Exception{
		openConnection();
		try {
            String l_cri = " where d.departmentName like '%" + cri.getKeyword() + "%'";
            String l_searchQuery = "select d from Department d" + l_cri;
            
            List<Department> l_entityList = entityManager.createQuery(l_searchQuery, Department.class)
                    .setFirstResult(cri.getIndex() * cri.getSize())
                    .setMaxResults(cri.getSize())
                    .getResultList();
            
            DepartmentDataList l_dataList = new DepartmentDataList();
            l_dataList.setEntityList(l_entityList);
            
            if(cri.getIndex() == 0){
            	String l_countQuery = "select count(d.departmentID) from Department d" + l_cri;
            	l_dataList.setTotalRecord(entityManager.createQuery(l_countQuery, Long.class).getSingleResult());
            }
			return l_dataList;
		} catch (Exception e) {
			throw e;
		} finally{
			closeConnection();
		}
	}
	
	public List<Department> findAll(long parentId)throws  Exception{
		openConnection();
		try {
			if(parentId == 0)
				return entityManager.createNamedQuery("Department.findAll", Department.class).getResultList();
			else
				return entityManager.createNamedQuery("Department.findAllByParent", Department.class).setParameter("parentID", parentId).getResultList();
		} catch (Exception e) {
			throw e;
		} finally {
			closeConnection();
		}
	}
	
	public List<Department> findAllByBranch(long branchId)throws Exception{
		openConnection();
		try {
			return entityManager.createNamedQuery("Department.findAllByBranch", Department.class).setParameter("branchId", branchId).getResultList();
		} catch (Exception e) {
			throw e;
		}
	}
}
